package connection;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import connection.exception.ConnectionResetException;

import server.ServerData;

/**
 * The Class ServerTCPSocket creates an abstraction to create new connections to the server.
 */
public class TCPServerSocket {
	
	
	/** The ServerSocket that will be used to create the new connections. */
	private ServerSocket _serverSocket;
	
	/** The amount of time that the socket will be blocked waiting for connections*/
	private int timeout = 40000;
	
	/** The reference to the object that contains the log to which will be sent the runtime info.*/
	private ServerData _serverData;
		

	/**
	 * Instantiates a new ServerSocket. We take as default the server port 9090 on witch the server will
	 * listen for new connections.
	 */
	public TCPServerSocket(ServerData serverData){
		_serverData = serverData;
		try {
			_serverSocket = new ServerSocket(9090);
			_serverSocket.setSoTimeout(timeout);
			//_serverData.writeToLog("Server Socket created on the address: "+getServerSocketAddress());
		} catch (IOException e) {
			
			e.printStackTrace();
		}
	}	
	
	
	/**
	 * That blocking method will wait to a connection from a client to happens and then create a new socket
	 * and return him.
	 * 
	 * @return the TCPSocket to where the client is connected.
	 */
	public TCPSecureServerSocket connect() {
		Socket _socket = new Socket();
		TCPSecureServerSocket _tcpSecureSocket = null;
		
		try {
			_socket = _serverSocket.accept();
			_tcpSecureSocket = new TCPSecureServerSocket(new TCPSocket(_socket));		
			_serverData.writeToLog("Socket coonected successfully to "+_socket.getRemoteSocketAddress());
		}catch (SocketTimeoutException e){
			return null;
		} catch (IOException e) {
			_serverData.writeToLog(e.getMessage());
			e.printStackTrace();
		} catch (ConnectionResetException e) {
			return null;
		}		
		return _tcpSecureSocket;		
	}
	
	/**
	 * Close the socket when him is no more needed.
	 */
	public void close(){
		try {
			_serverSocket.close();
		} catch (IOException e) {
			_serverData.writeToLog("Excep��o lançada ao tentar fechar o server socket: "+e.getMessage());
			e.printStackTrace();
		}
	}
	
	
	/**
	 * Gets the ServerSocket address.
	 * 
	 * @return the InetSocketAddress of this ServerSocket.
	 * @exception if this cannot find the host catch an UnknownHostException.
	 */
	public InetSocketAddress getServerSocketAddress() {
		InetSocketAddress inet = null;
		try {
			inet = new InetSocketAddress(InetAddress.getLocalHost(), _serverSocket.getLocalPort());
		} catch (UnknownHostException e) {			
			e.printStackTrace();
		}
		return inet;
	}
}
